#ifndef IMAGEUTILITY_H
#define IMAGEUTILITY_H

#include <QImage>

#include <opencv/cv.h>

class ImageUtility
{
public:
    ImageUtility();
    enum Channel {
        RED_CHANNEL,
        GREEN_CHANNEL,
        BLUE_CHANNEL,
        RGB_COMBO,
        HSV_HUE_CHANNEL,
        HSV_SATURATION_CHANNEL,
        HSV_VALUE_CHANNEL
    };

    enum BlurType {
        BLUR = CV_BLUR,
        MEDIAN = CV_MEDIAN,
        GAUSSIAN = CV_GAUSSIAN,
        BILATERAL = CV_BILATERAL
    };

    static QImage IplImageToQImage(IplImage* image);
    static IplImage* QImageToIplImage(QImage image);
    static QImage clone(QImage image);

    static QImage convertFromLogRGB(QImage image);
    static QImage convertToLogRGB(QImage image);
    static QImage convertToGrayscale(QImage image, enum Channel channel = RGB_COMBO);
    static QImage erode(QImage image, int iterations);
    static QImage dilate(QImage image, int iterations);
    static QImage smooth(QImage image, int kernelSize, BlurType blurType);
    static QImage gradientMagnitude(QImage image);
    static QImage gradientOrientation(QImage image);
    static QVector<QImage> gradientXY(QImage image);
    static QImage differenceOfGaussians(QImage image, int firstKernelSize = 9, int secondKernelSize = 5);
    static float minValue(QImage image, Channel channel, QImage mask = QImage());
    static float maxValue(QImage image, Channel channel, QImage mask = QImage());
    static QVector<QVector<int> > histogram(QImage image, QImage mask = QImage());
    static QVector<int> histogram(QImage image, Channel channel, QImage mask = QImage());
    static QImage equalizeHistogram(QImage image, QImage mask = QImage());
    static QImage equalizeHistogram(QImage image, Channel channel, QImage mask = QImage());
    static QVector<float> equalizedHistogramLookupTable(QImage image, Channel channel, QImage mask = QImage());
    static QVector<float> equalizedHistogramInverseLookupTable(QImage image, Channel channel, QImage mask = QImage());
    static QVector<int> equalizedHistogram(QImage image, Channel channel, QImage mask = QImage());
    static QVector<float> normalizedHistogram(QImage image, Channel channel, QImage mask = QImage());
    static QVector<float> specifiedHistogram(QImage source, QImage destination,
                                             Channel sourceChannel, Channel destinationChannel,
                                             QImage sourceMask = QImage(), QImage destinationMask = QImage());
    static QImage specifyHistogram(QImage source, QImage destination,
                                   QImage sourceMask = QImage(), QImage destinationMask = QImage());
    static QImage specifyHistogram(QImage source, QImage destination,
                                   Channel sourceChannel, Channel destinationChannel,
                                   QImage sourceMask = QImage(), QImage destinationMask = QImage());
    static QVector<QVector<float> > normalizedHistogram(QImage image, QImage mask = QImage());
    static QImage invert(QImage image);
    static void normalize(IplImage* image);
    static QImage normalize(QImage image);
    static QImage add(QImage first, QImage second);
    static QImage subtract(QImage first, QImage second);
    static QImage scale(QImage image, float scaleFactor);
    static QImage fillHoles(QImage image, int pixelLength);
    static QImage changeColor(QImage image, QColor oldColor, QColor newColor);
    static double findLineAngle(QLine line);
    static double findLineAngle(QLineF line);
    static double findLineAngle(double dx, double dy);
    static QLineF findNormal(QLineF line);
    static QLine findNormal(QLine line);
    static QLine findLineThroughPoint(QLine line, QPoint point, float radius = 1.0f);
    static double lineDistanceToPoint(QLine line, QPoint point);
    static QLine findLineClosestToPoint(QVector<QLine>& lines, QPoint point);
    static QVector<QLine> findEdgeNormals(QImage image, float insidePixelWidth, float outsidePixelWidth);
    static QLine findLineInMask(QPoint point, int dx, int dy, QImage mask);
    static QVector<QPoint> getRasterizedPointsAlongLine(QLine line, QImage mask = QImage());
    static QVector<QColor> getImageValuesAlongLine(QImage image, QLine line);
    static QVector<int> getImageValuesAlongLine(QImage image, QLine line, enum Channel channel);
    static QImage createLineImage(QVector<QLine> lines, QSize size, QVector<QColor> lineColors, QColor backgroundColor, QVector<float> lineWidths = QVector<float>());
    static QImage createLineImage(QVector<QLine> lines, QSize size, QColor lineColor, QColor backgroundColor, float lineWidth = 1.0f);
};

#endif // IMAGEUTILITY_H
